package com.heaboy.feedback.websocket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class WsServer implements CommandLineRunner {

    @Value("${netty.ws.port}")
    private  int port;

    @Autowired
    private WsContineHandler wsContineHandler;

    @Autowired
    private WsWebSocketHandler wsWebSocketHandler;


    public void teacherStart(int port) throws InterruptedException {
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup(2);
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap()
                    .group(boss, worker)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel nsc) throws Exception {
                            nsc.pipeline().addLast(new HttpServerCodec());
                            nsc.pipeline().addLast(new HttpObjectAggregator(65536));
                            nsc.pipeline().addLast(wsContineHandler);
                            nsc.pipeline().addLast(new WebSocketServerProtocolHandler("/ws", null, true, 65536 * 10, false, true));
                            nsc.pipeline().addLast(wsWebSocketHandler);
                        }
                    });
            ChannelFuture cf = serverBootstrap.bind(port).sync();
            log.info("课堂服务已开启,port=" + port);
            cf.channel().closeFuture().sync();
        } finally {
            boss.shutdownGracefully().sync(); // 释放线程池资源
            worker.shutdownGracefully().sync();
        }
    }

    public void init(int port) {
        new Thread(() -> {
            try {
                teacherStart(port);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }


    @Override
    public void run(String... args) throws Exception {
        init(port);
    }
}
